package com.hxzf.mvp.commons.domain;

import com.github.pagehelper.Page;
import com.hxzf.mvp.commons.constant.RespCode;
import io.swagger.annotations.ApiModel;
import io.swagger.annotations.ApiModelProperty;
import lombok.Getter;
import lombok.Setter;

import java.util.Collections;
import java.util.List;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * MyBatis分页结果容器
 *
 * <p>功能同PageInfo，额外支持转换器参数。
 * <p>一般与{@link com.hxzf.mvp.commons.domain.Pageable}结对出现。
 *
 * @param <T> Entity
 * @author Kai
 */
@Getter
@Setter
@ApiModel(value = "PageData", description = "分页数据")
public class PageData<T> extends Resp<T> {
    @ApiModelProperty(value = "总记录数")
    private long total;
    @ApiModelProperty(value = "结果集")
    private List<T> rows;
    @ApiModelProperty(value = "第几页")
    private int pageNum;
    @ApiModelProperty(value = "每页记录数")
    private int pageSize;
    @ApiModelProperty(value = "总页数")
    private int pages;

    private PageData(long total, List<T> rows, int pageNum, int pageSize, int pages) {
        super(RespCode.SUCCESS);
        this.total = total;
        this.rows = rows;
        this.pageNum = pageNum;
        this.pageSize = pageSize;
        this.pages = pages;
    }

    public PageData(List<T> rows) {
        super(RespCode.SUCCESS);
        if (rows instanceof Page) {
            Page<T> page = (Page<T>) rows;
            this.pageNum = page.getPageNum();
            this.pageSize = page.getPageSize();
            this.total = page.getTotal();
            this.pages = page.getPages();
        } else {
            // 即使没有发生分页，也要使参数正确
            int size = rows == null ? 0 : rows.size();
            this.pageNum = 1;
            this.pageSize = size;
            this.total = size;
            this.pages = 1;
        }

        this.rows = rows == null ? Collections.emptyList() : rows;
    }

    public <U> PageData<U> map(Function<? super T, ? extends U> converter) {
        return new PageData<>(this.total,
                this.rows.stream().map(converter).collect(Collectors.toList()),
                this.pageNum,
                this.pageSize,
                this.pages
        );
    }
}